package cn.elwy.rcp.ui.composite;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class TitleAreaComposite extends BaseComposite {

  private boolean isCreateHeade = true;

  private String message = ""; //$NON-NLS-1$
  private String errorMessage;

  private Label titleLabel;
  private Label titleImageLabel;
  // private Label bottomFillerLabel;
  // private Label leftFillerLabel;
  // private RGB titleAreaRGB;
  // private Color titleAreaColor;
  private Text messageLabel;
  private Composite contents;
  private Composite dialogArea;
  private Label messageImageLabel;
  private Image messageImage;
  private boolean showingError = false;

  private boolean titleImageLargest = true;

  private Image titleAreaImage;

  // private int messageLabelHeight;
  // private static final int H_GAP_IMAGE = 5;

  public static final String DLG_IMG_TITLE_BANNER = "dialog_title_banner_image";//$NON-NLS-1$
  public static final String DLG_IMG_MESSAGE_INFO = "dialog_messasge_info_image"; //$NON-NLS-1$
  public static final String DLG_IMG_MESSAGE_WARNING = "dialog_messasge_warning_image"; //$NON-NLS-1$
  public static final String DLG_IMG_MESSAGE_ERROR = "dialog_message_error_image"; //$NON-NLS-1$
  private Composite monitorComposite;

  /**
   * Create the dialog.
   * 
   * @param parent
   * @param style
   */
  public TitleAreaComposite(Composite parent, int style) {
    super(parent, style);
    GridLayout gridLayout = new GridLayout(1, false);
    gridLayout.verticalSpacing = 0;
    gridLayout.marginWidth = 0;
    gridLayout.marginHeight = 0;
    gridLayout.horizontalSpacing = 0;
    setLayout(gridLayout);

    // createContents();
  }

  public void createContents() {
    createContents(this);
  }

  protected Control createContents(Composite parent) {
    contents = new Composite(parent, SWT.NONE);
    contents.setLayoutData(new GridData(GridData.FILL_BOTH));
    GridLayout gl_contents = new GridLayout(1, false);
    gl_contents.verticalSpacing = 0;
    gl_contents.marginWidth = 0;
    gl_contents.marginHeight = 0;
    gl_contents.horizontalSpacing = 0;
    contents.setLayout(gl_contents);

    applyDialogFont(contents);
    initializeDialogUnits(contents);

    applyDialogFont(contents);

    if (isCreateHeade) {
      createHeaderArea(contents);
    }

    dialogArea = createDialogArea(contents);

    createProgressMonitorPart(contents);

    Composite bottomArea = new Composite(contents, SWT.NONE);
    GridLayout gl_bottomArea = new GridLayout(1, false);
    gl_bottomArea.verticalSpacing = 0;
    gl_bottomArea.marginHeight = 0;
    gl_bottomArea.marginWidth = 0;
    bottomArea.setLayout(gl_bottomArea);
    bottomArea.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false, 1, 1));

    createButtonBar(bottomArea);

    return contents;
  }

  protected void createHeaderArea(Composite parent) {
    Composite headerArea = new Composite(parent, SWT.NONE);
    headerArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
    GridLayout gl_headerArea = new GridLayout(2, false);
    gl_headerArea.verticalSpacing = 0;
    gl_headerArea.marginWidth = 0;
    gl_headerArea.marginHeight = 0;
    gl_headerArea.horizontalSpacing = 0;
    headerArea.setLayout(gl_headerArea);

    Display display = parent.getDisplay();
    Color background = JFaceColors.getBannerBackground(display);
    Color foreground = JFaceColors.getBannerForeground(display);

    headerArea.setBackgroundMode(SWT.BACKGROUND);
    headerArea.setBackground(background);

    applyDialogFont(headerArea);

    Composite titleArea = new Composite(headerArea, SWT.NONE);
    titleArea.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true, 1, 1));
    GridLayout gl_titleArea = new GridLayout(2, false);
    gl_titleArea.marginLeft = 5;
    gl_titleArea.verticalSpacing = 10;
    gl_titleArea.marginHeight = 0;
    gl_titleArea.horizontalSpacing = 0;
    titleArea.setLayout(gl_titleArea);
    GridData gd_titleArea = new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1);
    gd_titleArea.heightHint = 60;
    gd_titleArea.minimumHeight = 60;
    titleArea.setLayoutData(gd_titleArea);
    GridData gd_remarkLabel = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
    gd_remarkLabel.horizontalIndent = 12;

    titleLabel = new Label(titleArea, SWT.LEFT);
    titleLabel.setText("title");
    JFaceColors.setColors(titleLabel, foreground, background);
    titleLabel.setFont(JFaceResources.getBannerFont());
    GridData gd_titleLabel = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
    gd_titleLabel.verticalIndent = 5;
    titleLabel.setLayoutData(gd_titleLabel);

    messageImageLabel = new Label(titleArea, SWT.CENTER);
    GridData gd_messageImageLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
    gd_messageImageLabel.widthHint = 16;
    gd_messageImageLabel.minimumWidth = 16;
    messageImageLabel.setLayoutData(gd_messageImageLabel);
    messageImageLabel.setImage(JFaceResources.getImage(DLG_IMG_MESSAGE_ERROR));
    messageImageLabel.setBackground(background);

    messageLabel = new Text(titleArea, SWT.WRAP | SWT.READ_ONLY);
    messageLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
    JFaceColors.setColors(messageLabel, foreground, background);
    messageLabel.setText("errorMessage"); //$NON-NLS-1$
    messageLabel.setFont(JFaceResources.getDialogFont());
    // messageLabelHeight = messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;

    titleImageLabel = new Label(headerArea, SWT.CENTER);
    titleImageLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1));
    titleImageLabel.setImage(JFaceResources.getImage(DLG_IMG_TITLE_BANNER));
    if (titleAreaImage == null) {
      titleImageLabel.setImage(JFaceResources.getImage(DLG_IMG_TITLE_BANNER));
    } else {
      titleImageLabel.setImage(titleAreaImage);
    }

    Label headerSeparator = new Label(headerArea, SWT.SEPARATOR | SWT.HORIZONTAL);
    GridData gd_headerSeparator = new GridData(GridData.FILL_HORIZONTAL);
    gd_headerSeparator.horizontalSpan = 2;
    headerSeparator.setLayoutData(gd_headerSeparator);

    headerArea.setFont(JFaceResources.getDialogFont());
    initializeDialogUnits(headerArea);
  }

  protected Composite createDialogArea(Composite contentCompisite) {
    Composite bodyArea = new Composite(contentCompisite, SWT.NONE);
    GridLayout gl_bodyArea = new GridLayout(1, false);
    gl_bodyArea.horizontalSpacing = 0;
    gl_bodyArea.marginHeight = 0;
    gl_bodyArea.marginWidth = 0;
    gl_bodyArea.verticalSpacing = 0;
    bodyArea.setLayout(gl_bodyArea);
    bodyArea.setLayoutData(new GridData(GridData.FILL_BOTH));
    applyDialogFont(bodyArea);
    return bodyArea;
  }

  protected void createProgressMonitorPart(Composite parent) {
    monitorComposite = new Composite(parent, SWT.NONE);
    monitorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    GridLayout gl_monitorComposite = new GridLayout(1, false);
    gl_monitorComposite.horizontalSpacing = 0;
    gl_monitorComposite.verticalSpacing = 0;
    gl_monitorComposite.marginWidth = 0;
    gl_monitorComposite.marginHeight = 0;
    monitorComposite.setLayout(gl_monitorComposite);
  }

  protected Composite createButtonBar(Composite parent) {
    Label bottomSeparator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
    bottomSeparator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
    Composite buttonComposite = new Composite(parent, SWT.NONE);
    GridLayout gl_buttonComposite = new GridLayout(2, false);
    gl_buttonComposite.marginHeight = 10;
    buttonComposite.setLayout(gl_buttonComposite);
    buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));

    createHelpBar(buttonComposite);

    createButtonsForButtonBar(buttonComposite);

    return buttonComposite;
  }

  protected Composite createHelpBar(Composite parent) {
    Composite helpBar = new Composite(parent, SWT.NONE);

    GridLayout gl_helpBar = new GridLayout(1, false);
    gl_helpBar.marginHeight = 10;
    helpBar.setLayout(gl_helpBar);
    helpBar.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, true, true, 1, 1));

    if (isHelpAvailable()) {
      Control helpControl = createHelpControl(helpBar);
      ((GridData) helpControl.getLayoutData()).horizontalIndent = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
    }
    return helpBar;
  }

  protected void createProgressMonitorPart() {
    progressMonitorPart = createProgressMonitorPart(monitorComposite, new GridLayout());
  }

  public void setTitle(String title) {
    if (titleLabel == null || title == null) {
      return;
    }
    titleLabel.setText(title);
  }

  public void setTitleImage(Image titleImage) {
    titleAreaImage = titleImage;
    if (titleImageLabel != null && titleImage != null) {
      titleImageLabel.setImage(titleImage);
    }
  }

  public void setErrorMessage(String newErrorMessage) {
    // Any change?
    if (errorMessage == null ? newErrorMessage == null : errorMessage.equals(newErrorMessage))
      return;
    errorMessage = newErrorMessage;

    // Clear or set error message.
    if (errorMessage == null) {
      if (showingError) {
        // we were previously showing an error
        showingError = false;
      }
      // show the message
      // avoid calling setMessage in case it is overridden to call
      // setErrorMessage,
      // which would result in a recursive infinite loop
      if (message == null) // this should probably never happen since
        // setMessage does this conversion....
        message = ""; //$NON-NLS-1$
      updateMessage(message);
      updateMessageImage(messageImage);
      setImageLabelVisible(messageImage != null);
    } else {
      // Add in a space for layout purposes but do not
      // change the instance variable
      String displayedErrorMessage = errorMessage; //$NON-NLS-1$
      updateMessage(displayedErrorMessage);
      if (!showingError) {
        // we were not previously showing an error
        showingError = true;
        messageImageLabel.setImage(JFaceResources.getImage(DLG_IMG_MESSAGE_ERROR));
        setImageLabelVisible(true);
      }
    }
    // layoutForNewMessage(false);
  }

  private void setImageLabelVisible(boolean visible) {
    if (messageImageLabel != null) {
      messageImageLabel.setVisible(visible);
    }
    // bottomFillerLabel.setVisible(visible);
    // leftFillerLabel.setVisible(visible);
  }

  public void setMessage(String newMessage) {
    setMessage(newMessage, IMessageProvider.NONE);
  }

  public void setMessage(String newMessage, int newType) {
    Image newImage = null;
    if (newMessage != null) {
      switch (newType) {
      case IMessageProvider.NONE:
        break;
      case IMessageProvider.INFORMATION:
        newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_INFO);
        break;
      case IMessageProvider.WARNING:
        newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_WARNING);
        break;
      case IMessageProvider.ERROR:
        newImage = JFaceResources.getImage(DLG_IMG_MESSAGE_ERROR);
        break;
      }
    }
    showMessage(newMessage, newImage);
  }

  private void showMessage(String newMessage, Image newImage) {
    if (newMessage == null) {
      newMessage = ""; //$NON-NLS-1$
    }

    // Any change?
    if (message.equals(newMessage) && messageImage == newImage) {
      return;
    }
    message = newMessage;

    // Message string to be shown - if there is an image then add in
    // a space to the message for layout purposes
    String shownMessage = message; //$NON-NLS-1$  
    messageImage = newImage;
    if (!showingError) {
      // we are not showing an error
      updateMessage(shownMessage);
      updateMessageImage(messageImage);
      setImageLabelVisible(messageImage != null);
      // layoutForNewMessage(false);
    }
  }

  private void updateMessageImage(Image image) {
    if (messageImageLabel != null) {
      messageImageLabel.setImage(image);
    }
  }

  private void updateMessage(String newMessage) {
    if (messageLabel != null) {
      messageLabel.setText(newMessage);
    }
  }

  public boolean isCreateHeade() {
    return isCreateHeade;
  }

  public void setCreateHeade(boolean isCreateHeade) {
    this.isCreateHeade = isCreateHeade;
  }

  public Label getTitleLabel() {
    return titleLabel;
  }

  public void setTitleLabel(Label titleLabel) {
    this.titleLabel = titleLabel;
  }

  public Label getTitleImageLabel() {
    return titleImageLabel;
  }

  public void setTitleImageLabel(Label titleImageLabel) {
    this.titleImageLabel = titleImageLabel;
  }

  public Text getMessageLabel() {
    return messageLabel;
  }

  public void setMessageLabel(Text messageLabel) {
    this.messageLabel = messageLabel;
  }

  public Composite getContents() {
    return contents;
  }

  public void setContents(Composite contents) {
    this.contents = contents;
  }

  public Control getDialogArea() {
    return dialogArea;
  }

  public void setDialogArea(Composite dialogArea) {
    this.dialogArea = dialogArea;
  }

  public Label getMessageImageLabel() {
    return messageImageLabel;
  }

  public void setMessageImageLabel(Label messageImageLabel) {
    this.messageImageLabel = messageImageLabel;
  }

  public Image getMessageImage() {
    return messageImage;
  }

  public void setMessageImage(Image messageImage) {
    this.messageImage = messageImage;
  }

  public boolean isShowingError() {
    return showingError;
  }

  public void setShowingError(boolean showingError) {
    this.showingError = showingError;
  }

  public boolean isTitleImageLargest() {
    return titleImageLargest;
  }

  public void setTitleImageLargest(boolean titleImageLargest) {
    this.titleImageLargest = titleImageLargest;
  }

  public Image getTitleAreaImage() {
    return titleAreaImage;
  }

  public void setTitleAreaImage(Image titleAreaImage) {
    this.titleAreaImage = titleAreaImage;
  }

  public String getMessage() {
    return message;
  }

  public String getErrorMessage() {
    return errorMessage;
  }
}
